﻿namespace Sofire.Data
{
    using System;
    using System.Data;
    using System.Data.Common;
    using System.Data.SQLite;

    /// <summary>
    /// 基于 SQLite 查询与交互的操作引擎。
    /// </summary>
    [Serializable]
    public class SQLiteQuery : QueryEngineBase
    {
        #region Constructors

        /// <summary>
        /// 初始化 <see cref="Sofire.Data.SQLiteQuery"/> 的新实例。
        /// </summary>
        /// <param name="connectionString">连接字符串。</param>
        public SQLiteQuery(string connectionString)
            : base(QueryEngineProvider.SQLite, connectionString)
        {
        }

        /// <summary>
        /// 初始化 <see cref="Sofire.Data.SQLiteQuery"/> 的新实例。
        /// </summary>
        /// <param name="filename">文件路径。</param>
        /// <param name="passwrod">密码，如果为空值则忽略。</param>
        public SQLiteQuery(string filename, string passwrod)
        {
            var connectionString = "Data Source=" + filename + ";Version=" + SQLiteConnection.SQLiteVersion.Substring(0, SQLiteConnection.SQLiteVersion.IndexOf('.'));
            if(!string.IsNullOrEmpty(passwrod))
            {
                connectionString += ";Password=" + passwrod;
            }
            base.Initialization(QueryEngineProvider.SQLite, connectionString);
        }

        #endregion Constructors

        #region Methods

        // SQL语句：http://www.connectionstrings.com/sqlite
        /// <summary>
        /// 给定数据库文件地址，创建一个新的数据库文件。
        /// </summary>
        /// <param name="databaseFilename">数据库文件地址。</param>
        public static void CreateFile(string databaseFilename)
        {
            SQLiteConnection.CreateFile(databaseFilename);
        }

        /// <summary>
        /// 修改 SQLite 数据库的密码。
        /// </summary>
        /// <param name="newPassword">新密码。</param>
        public Result ChangePassword(string newPassword)
        {
            SQLiteConnection conn = null;
            try
            {
                using(conn = this.CreateSQLiteConnection())
                {
                    conn.Open();
                    conn.ChangePassword(newPassword);
                }
                return Result.Successfully;
            }
            catch(Exception ex)
            {
                return ex;
            }
            finally
            {
                conn.TryClose();
            }
        }

        /// <summary>
        /// 创建并返回一个 <see cref="System.Data.SQLite.SQLiteCommandBuilder"/> 查询命令生成器。
        /// </summary>
        /// <returns>返回一个查询命令生成器。</returns>
        public override DbCommandBuilder CreateCommandBuilder()
        {
            return new SQLiteCommandBuilder();
        }

        /// <summary>
        /// 创建并返回一个 <see cref="System.Data.SQLite.SQLiteConnection"/> 数据源。
        /// </summary>
        /// <returns>返回一个数据库的连接。</returns>
        public override DbConnection CreateConnection()
        {
            return this.CreateSQLiteConnection();
        }

        /// <summary>
        /// 创建并返回一个 <see cref="System.Data.SQLite.SQLiteDataAdapter"/> 数据适配器。
        /// </summary>
        /// <param name="command">命令对象。</param>
        /// <returns>返回一个数据适配器。</returns>
        public override DbDataAdapter CreateDataAdapter(DbCommand command)
        {
            return new SQLiteDataAdapter(command as SQLiteCommand);
        }

        /// <summary>
        /// 创建并返回一个 <see cref="System.Data.SQLite.SQLiteConnection"/> 数据源。
        /// </summary>
        /// <returns>返回一个数据库的连接。</returns>
        public SQLiteConnection CreateSQLiteConnection()
        {
            return new SQLiteConnection(this.ConnectionString);
        }

        /// <summary>
        /// 设置 SQLite 数据库的密码。
        /// </summary>
        /// <param name="password">密码。</param>
        public Result SetPassword(string password)
        {
            SQLiteConnection conn = null;
            try
            {
                using(conn = this.CreateSQLiteConnection())
                {
                    conn.Open();
                    conn.SetPassword(password);
                }
                return Result.Successfully;
            }
            catch(Exception ex)
            {
                return ex;
            }
            finally
            {
                conn.TryClose();
            }
        }

        #endregion Methods


        /// <summary>
        /// 描述指定的 <see cref="System.Data.Common.DbParameter"/>。
        /// </summary>
        /// <param name="parameter">一个 <see cref="System.Data.Common.DbParameter"/> 的实例。</param>
        /// <returns>返回参数描述的 <see cref="System.String"/> 值。</returns>
        public override string DescribeParameter(DbParameter parameter)
        {
            var p = parameter as SQLiteParameter;
            string desc = p.ParameterName;
            
            switch(p.Direction)
            {
                case ParameterDirection.InputOutput:
                    desc += " IN OUT";
                    break;
                case ParameterDirection.Output:
                    desc += " OUT";
                    break;
            }
            desc += " " + p.DbType;
            switch(p.DbType)
            {
                case DbType.VarNumeric:
                case DbType.Single:
                case DbType.Double:
                case DbType.Decimal:
                case DbType.Binary:
                    desc += "(" + p.Size + ")";
                    break;
            }
            return desc;
        }
    }
}